package org.azj.dbOperatorComponent;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import org.azj.fieldTypeConverter.ConverterFactory;
import org.azj.fieldTypeConverter.ITypeConverter;
import org.azj.fieldTypeConverter.TypeParseException;
import org.azj.logHelper.LOG;
import org.azj.logHelper.LOG_COMPONENT;
import org.azj.logHelper.LOG_LEVEL;

public class InsertPartialCommand extends DbNonQueryCommand {

	HashMap<String, String> contents;
	String tableFullName;
	HashMap<String, IColumnProperty> columnPropertyHashMap;
	
	IDealBlobStrategy blobMethod;
	
	public InsertPartialCommand(
			String tableName, 
			HashMap<String, String> contents,
			HashMap<String , IColumnProperty> columnProperty,
			IDealBlobStrategy blobMethod)
	{
		this.tableFullName = tableName;	
		this.contents = contents;
		this.columnPropertyHashMap = columnProperty;
		this.blobMethod = blobMethod;
	}

	@Override
	public PreparedStatement getStatement(Connection conn) throws Exception
	{	
		HashMap<String, String> colsAsBlob = new HashMap<String, String>();
		
		StringBuffer columnsBuffer = new StringBuffer();
		StringBuffer valuesBuffer = new StringBuffer();
		
		Set<String> keys = contents.keySet();
		Iterator<String> it = keys.iterator();
		
		int valueCount = 0;
		while (it.hasNext()) {
			valueCount++;
			
			String columnName = it.next();
			if (columnName.lastIndexOf('.') == -1)
			{
				// add full name
				columnName = tableFullName + "." + columnName;
			}
			
			columnsBuffer.append(columnName + ",");
			
			// find the type this column corresponds to
			IColumnProperty property = columnPropertyHashMap.get(columnName.toUpperCase());
			String typeNameString = property.getDataTypeName();
			ITypeConverter converter = ConverterFactory.GetConverterByFieldType(typeNameString);
			String value = "";
			try {
				value = converter.Convert(contents.get(columnName), columnName);
				if (value.equals("?") == true) {
					colsAsBlob.put(String.valueOf(valueCount), contents.get(columnName));
				}
			} catch (TypeParseException e) {
				LOG.WriteLog(LOG_LEVEL.OPERATIONAL, LOG_COMPONENT.LOG_COMP_DB_CHANGE, "数据转换时出现问题 :" + e.getMessage());
				throw e;
			}
			
			valuesBuffer.append(value + ",");
		}
		
		// remove the last comma
		columnsBuffer.deleteCharAt(columnsBuffer.length() - 1);
		valuesBuffer.deleteCharAt(valuesBuffer.length() - 1);
	
		// deal with blob column
		PreparedStatement preparedStatement = conn.prepareStatement(
				String.format("INSERT INTO %s(%s) VALUES (%s)", 
				tableFullName, columnsBuffer.toString(), valuesBuffer.toString()));
		
		// check if needs extra fill for blob
		if (colsAsBlob.isEmpty() == false) {
			// find all '?' in the values buffer, "?" means the column that needs 
			// to set as Blob
			Set<String> numStrs = colsAsBlob.keySet();
			for (String numStr : numStrs) {
				int needsRectifyIndex = Integer.parseInt(numStr);
				blobMethod.dealBlob(preparedStatement, needsRectifyIndex, colsAsBlob.get(numStr));
			}
		}
		
		return preparedStatement;
	}
	
	@Override
	void doExecute(PreparedStatement preparedStatement) throws SQLException{
		preparedStatement.execute();
		blobMethod.close();
	}
}
